/*
 SplatterViewController.m
 
 The main view controller which sets up and handles a majority of the user interface.
 
 Created by David Kikuta.
 */

#import "SplatterViewController.h"
#import "UISegmentedControlExtension.h"
#import "SplatterAppDelegate.h"

#define kTagFirst 111
#define kTagSecond 112
#define kTagThird 113
#define kTagFourth 114
#define kTagFifth 115

#define kActivationInset 10

#define widthMultiplier 10
#define colorSpotX 30
#define colorSpotY 25

@implementation SplatterViewController

@synthesize canvasView, loadingViewController, capturedImages, confirmationViewController;

#pragma mark -
#pragma mark File Handling

- (void)saveImage {
    UIImageWriteToSavedPhotosAlbum(canvasView.image, nil,nil,nil);
    [self closeConfirmationWindow];
}

// Creates the ImagePicker window for loading an image.
- (void)showImagePicker:(UIImagePickerControllerSourceType)sourceType {
    if (self.canvasView.isAnimating) {
        self.canvasView.stopAnimating;
    }
	
    if (self.capturedImages.count > 0) {
        [self.capturedImages removeAllObjects];
    }
	
    if ([UIImagePickerController isSourceTypeAvailable:sourceType]) {
		openWindow = [[UIPopoverController alloc] initWithContentViewController:self.loadingViewController.imagePickerController];		
		[openWindow presentPopoverFromBarButtonItem:openNavButton permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];	
    }
}

// Brings up or dismisses the load window.
- (IBAction)photoLibraryAction:(id)sender {
	if([openWindow isPopoverVisible]) {
		[openWindow dismissPopoverAnimated:YES];
    }
    else {
	    [self showImagePicker:UIImagePickerControllerSourceTypePhotoLibrary];
    }
}

// Displays the selected image on the canvas.
- (void)finishedPicking {
    // we took multiple shots, use the list of images for animation
    canvasView.image = [self.capturedImages objectAtIndex:0];
	
    [openWindow dismissPopoverAnimated:YES];
	
    canvasView.startAnimating;
}

- (void)didTakePicture:(UIImage *)picture {
    [self.capturedImages addObject:picture];
}

#pragma mark -
#pragma mark UIControl

- (void)updateColorSpot {
    currentColorView.image = nil;
	
	//draw colored circle	
    UIGraphicsBeginImageContext(currentColorView.frame.size);
    [currentColorView.image drawInRect:CGRectMake(0, 0, 60, 70)];
    CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
    CGContextSetLineWidth(UIGraphicsGetCurrentContext(), brushWidth);
    CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), red, green, blue, 1.0);
    CGContextMoveToPoint(UIGraphicsGetCurrentContext(), colorSpotX, colorSpotY);
    CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), colorSpotX, colorSpotY);
    CGContextStrokePath(UIGraphicsGetCurrentContext());
    CGContextFlush(UIGraphicsGetCurrentContext());
    currentColorView.image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
}

- (void)updateColorUI {
	red = [chooser red];
	green = [chooser green];
	blue = [chooser blue];
	
	NSString *colorString = [NSString stringWithFormat:@"(%3.3f, %3.3f, %3.3f)", red, green, blue];
	[self updateColorSpot];
	[currentColor setText:colorString];
}

-(void)setTextColorsForSegmentedControl:(UISegmentedControl*)segmented {
	[segmented setTextColor:[UIColor whiteColor] forTag:kTagFirst];
	[segmented setTextColor:[UIColor whiteColor] forTag:kTagSecond];
	[segmented setTextColor:[UIColor whiteColor] forTag:kTagThird];
	[segmented setTextColor:[UIColor whiteColor] forTag:kTagFourth];
	[segmented setTextColor:[UIColor blackColor] forTag:kTagFifth];
}

-(void)segmentChanged:(id)sender {
	// when a segment is selected, it resets the text colors
	// so set them back
	[self setTextColorsForSegmentedControl:(UISegmentedControl*)sender];
}

#pragma mark -
#pragma mark Button Handling

- (IBAction)saveButtonPressed:(UIBarButtonItem *)sender {	
	if([confirmWindow isPopoverVisible]) {
		[self closeConfirmationWindow];
	}
	else {
		[confirmationViewController setMessage:0];
		CGSize viewSize = CGSizeMake(320.0, 200.0);
		[confirmWindow setPopoverContentSize:viewSize animated:NO];
		[confirmWindow presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];			
	}
}

- (IBAction)newButtonPressed:(UIBarButtonItem *)sender {
	if([confirmWindow isPopoverVisible]) 
	{
		[confirmWindow dismissPopoverAnimated:YES];
	}
	else 
	{
		[confirmationViewController setMessage:1];
		CGSize viewSize = CGSizeMake(320.0, 200.0);
		[confirmWindow setPopoverContentSize:viewSize animated:NO];
		[confirmWindow presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
	}
}

- (IBAction)connectButtonPressed:(UIBarButtonItem *)sender {
	[(SplatterAppDelegate*)[[UIApplication sharedApplication] delegate] disconnectStreams];
	
	NSString *name = [(SplatterAppDelegate*)[[UIApplication sharedApplication] delegate] serverName];
	[(SplatterAppDelegate*)[[UIApplication sharedApplication] delegate] presentPicker:name];
}

- (void)closeConfirmationWindow {
	[confirmWindow dismissPopoverAnimated:YES];
}

- (IBAction)premadeColorSelected:(UISegmentedControl *)sender {
	float index = [sender selectedSegmentIndex];
	[chooser setPremadeValues:index];
	
	[redSlider setValue:[chooser red] animated:YES];
	[greenSlider setValue:[chooser green] animated:YES];
	[blueSlider setValue:[chooser blue] animated:YES];
	
	[self updateColorUI];
}

- (IBAction)showInformationWindow:(UIBarButtonItem *)sender {
	if ([infoWindow isPopoverVisible]) {
		[infoWindow dismissPopoverAnimated:YES];
	}
	else {
		CGSize viewSize = CGSizeMake(320.0, 300.0);
		[infoWindow setPopoverContentSize:viewSize animated:NO];
		[infoWindow presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
	}
}

- (IBAction)colorButtonPressed:(UIButton *)sender {
	if (colorView.hidden) {
		colorView.hidden = NO;
		showColors.hidden = YES;
		hideColors.hidden = NO;
	}
	else {
		colorView.hidden = YES;
		showColors.hidden = NO;
		hideColors.hidden = YES;
	}
}

- (IBAction)toolButtonPressed:(UIButton *)sender {
	if (toolView.hidden) {
		toolView.hidden = NO;
		showTools.hidden = YES;
		hideTools.hidden = NO;
	}
	else {
		toolView.hidden = YES;
		showTools.hidden = NO;
		hideTools.hidden = YES;
	}
}

#pragma mark -
#pragma mark Slider Handling

- (IBAction)widthSliderChanged:(UISlider *)sender {
	brushWidth = widthMultiplier * [widthSlider value];
	[self updateColorUI];
}

- (IBAction)redValueChanged:(UISlider *)sender {
	[chooser setRed:[sender value]];
	
	if ([premadeColors selectedSegmentIndex] != -1) {
		[premadeColors setSelectedSegmentIndex:UISegmentedControlNoSegment];
	}
	
	[self updateColorUI];
}

- (IBAction)greenValueChanged:(UISlider *)sender {
	[chooser setGreen:[sender value]];
	
	if ([premadeColors selectedSegmentIndex] != -1) {
		[premadeColors setSelectedSegmentIndex:UISegmentedControlNoSegment];
	}
	
	[self updateColorUI];
}

- (IBAction)blueValueChanged:(UISlider *)sender {
	[chooser setBlue:[sender value]];
	
	if ([premadeColors selectedSegmentIndex] != -1) {
		[premadeColors setSelectedSegmentIndex:UISegmentedControlNoSegment];
	}
	
	[self updateColorUI];
}

#pragma mark -
#pragma mark Drawing



- (void)clearCanvas {
	canvasView.image = nil;
	[self closeConfirmationWindow];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {	
	mouseSwiped = NO;
	UITouch *touch = [touches anyObject];
	
	if ([touch view] == canvasView) {
	    lastPoint = [touch locationInView:self.view];
	}
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
	mouseSwiped = YES;
	
	UITouch *touch = [touches anyObject];	
	
	if ([touch view] == canvasView) {
		CGPoint currentPoint = [touch locationInView:self.view];

		[self drawDot:brushWidth withPreviousPoint:lastPoint withCurrentPoint:currentPoint redVal:red greenVal:green blueVal:blue];
		
		// Store the values to be sent over a network.
		NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys: 
									[NSNumber numberWithFloat:brushWidth], @"width",
									[NSNumber numberWithFloat:lastPoint.x], @"previousx", 
									[NSNumber numberWithFloat:lastPoint.y], @"previousy",
									[NSNumber numberWithFloat:currentPoint.x], @"currentx",  
									[NSNumber numberWithFloat:currentPoint.y], @"currenty",
									[NSNumber numberWithFloat:red], @"red", 
									[NSNumber numberWithFloat:green], @"green", 
									[NSNumber numberWithFloat:blue], @"blue", nil];
		
		// Send the dictionary over the network.
		[(SplatterAppDelegate*)[[UIApplication sharedApplication] delegate] send:dictionary];
		
		lastPoint = currentPoint;			
	}
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
	if(!mouseSwiped) {
		[self drawDot:brushWidth withPreviousPoint:lastPoint withCurrentPoint:lastPoint redVal:red greenVal:green blueVal:blue];
		
		// Store the values to be sent over a network.
		NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys: 
									[NSNumber numberWithFloat:brushWidth], @"width",
									[NSNumber numberWithFloat:lastPoint.x], @"previousx", 
									[NSNumber numberWithFloat:lastPoint.y], @"previousy",
									[NSNumber numberWithFloat:lastPoint.x], @"currentx",  
									[NSNumber numberWithFloat:lastPoint.y], @"currenty",
									[NSNumber numberWithFloat:red], @"red", 
									[NSNumber numberWithFloat:green], @"green", 
									[NSNumber numberWithFloat:blue], @"blue", nil];
		
		// Send the dictionary over the network.
		[(SplatterAppDelegate*)[[UIApplication sharedApplication] delegate] send:dictionary];
	}
}

- (void)drawDot:(float)width withPreviousPoint:(CGPoint)previousPoint withCurrentPoint:(CGPoint)currentPoint redVal:(float)redValue greenVal:(float)greenValue blueVal:(float)blueValue {
	UIGraphicsBeginImageContext(self.view.frame.size);

	CGContextRef context = UIGraphicsGetCurrentContext();
	
	[canvasView.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
	CGContextSetLineCap(context, kCGLineCapRound);
	CGContextSetLineWidth(context, width);
	CGContextSetRGBStrokeColor(context, redValue, greenValue, blueValue, 1.0);
	CGContextMoveToPoint(context, previousPoint.x, previousPoint.y);
	CGContextAddQuadCurveToPoint(context, previousPoint.x, previousPoint.y, currentPoint.x, currentPoint.y);
	CGContextStrokePath(context);
	CGContextFlush(context);
	canvasView.image = UIGraphicsGetImageFromCurrentImageContext();
	UIGraphicsEndImageContext();	
}

#pragma mark -

- (void)viewDidLoad {	
	brushWidth = widthMultiplier;
	
	CGAffineTransform trans = CGAffineTransformMakeRotation(M_PI * 1.5);
	widthSlider.transform = trans;
	
	chooser = [[ColorChooser alloc] init];
	[chooser setRed:0];
	[chooser setGreen:0];
	[chooser setBlue:0];
		
	p = [[InformationViewController alloc] init];
	infoWindow = [[UIPopoverController alloc] initWithContentViewController:p];
		
	premadeColors.segmentedControlStyle = UISegmentedControlStyleBar;
	premadeColors.tintColor = [UIColor redColor];	
	
	// ... now to the interesting bits	
	// at some point later, the segment indexes change, so
	// must set tags on the segments before they render
	[premadeColors setTag:kTagFirst forSegmentAtIndex:0];
	[premadeColors setTag:kTagSecond forSegmentAtIndex:1];
	[premadeColors setTag:kTagThird forSegmentAtIndex:2];
	[premadeColors setTag:kTagFourth forSegmentAtIndex:3];
	[premadeColors setTag:kTagFifth forSegmentAtIndex:4];
	
	[premadeColors setTintColor:[UIColor redColor] forTag:kTagFirst];
	[premadeColors setTintColor:[UIColor greenColor] forTag:kTagSecond];
	[premadeColors setTintColor:[UIColor blueColor] forTag:kTagThird];
	[premadeColors setTintColor:[UIColor blackColor] forTag:kTagFourth];
	[premadeColors setTintColor:[UIColor lightGrayColor] forTag:kTagFifth];
	
	[self setTextColorsForSegmentedControl:premadeColors];
	[premadeColors release];
	
	self.loadingViewController =
	[[[LoadingViewController alloc] initWithNibName:@"LoadingViewController" bundle:nil] autorelease];	
	self.loadingViewController.delegate = self;
	
	self.confirmationViewController =
	[[[ConfirmationViewController alloc] init] autorelease];	
	self.confirmationViewController.delegate = self;

	confirmWindow = [[UIPopoverController alloc] initWithContentViewController:confirmationViewController];

	self.capturedImages = [NSMutableArray array];
	
	[self updateColorSpot];
	
	[super viewDidLoad];	
}

// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return NO;
}

- (void)didReceiveMemoryWarning {
	// Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
	
	// Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
	// Release any retained subviews of the main view.
	// e.g. self.myOutlet = nil;
	self.capturedImages = nil;

}

- (void)dealloc {
	[capturedImages release];
	[super dealloc];
}

@end
